layui.use(['element', 'jquery', "layer", "contextmenu", "common", "jquery-ui", "panzoom"], function() {
	var $ = layui.jquery;
	var elements = layui.element;
	elements.init();
	Array.prototype.notempty = function() {
		return this.filter(t => t != undefined && t !== null && t != '');
	}
	// 文件ID
	var fileID = $.Common.Utils.GetQueryString("id");
	

	$(".left-tool").contextMenu({
		width: 110, // width
		itemHeight: 30, // 菜单项height
		bgColor: "#333", // 背景颜色
		color: "#fff", // 字体颜色
		fontSize: 12, // 字体大小
		hoverBgColor: "#99CC66", // hover背景颜色
		target: function(ele) { // 当前元素
			//console.log(ele);
		},
		menu: [{ // 菜单项
			text: "新增",
			icon: "img/add.png",
			callback: function() {
				layui.layer.open({
					type: 2,
					resize: false,
					area: ['500px', '300px'],
					content: ['newfunc.html', 'no'],
					btn: ["确定", "取消"],
					yes: function(index, layero) {
						var body = layer.getChildFrame('body', index);
						var iframeWin = window[layero.find('iframe')[0]['name']]; //得到iframe页的窗口对象，执行iframe页的方法：iframeWin.method();
						var data = iframeWin.getForm();
						$.Project.addFile($.Project.File("", data.Name, data.Group, data.Category), function(fileRtn) {
							var tpl = $("#filetpl").html();
							$("#" + fileRtn.Category).append(laytpl(tpl).render({
								files: [fileRtn],
								type: fileRtn.Category
							}));
							$("#file_" + fileRtn.ID).click(function() {
								var id = $(this).attr("id");
								var name = $(this).text();
								var type = $(this).attr("data-type");
								c4uIndex.addTab(id, name, "url:html/" + type + "/index.html?id=" + id);
							});
							layui.layer.closeAll();
						});
					}
				});
			}
		}]
	});

	// 屏蔽图像区域右键菜单
	$(".flow-container").bind("contextmenu", function(e) {
		return false;
	});

	$(".layui-fluid").height($(window).height());
	$(".side-btn").click(function() {
		var v = $(this).parent().attr("target");
		var ih = $("." + v + "-tool").is(":hidden");
		if(ih) {
			if($("#main").hasClass("layui-col-sm10")) {
				$("#main").removeClass("layui-col-sm10").addClass("layui-col-sm8");
			} else {
				$("#main").removeClass("layui-col-sm12").addClass("layui-col-sm10");
			}

		} else {
			if($("#main").hasClass("layui-col-sm10")) {
				$("#main").removeClass("layui-col-sm10").addClass("layui-col-sm12");
			} else {
				$("#main").removeClass("layui-col-sm8").addClass("layui-col-sm10");
			}
		}
		$("." + v + "-tool").toggle();
		bindCompnetEvent(); // 重新绑定组件拖动区域
	});

	$(".jtk-node").click(function() {
		$(".jtk-node").removeClass("node-selected");
		$(this).addClass("node-selected");
	});
	// this is the paint style for the connecting lines..
	var connectorPaintStyle = {
			strokeWidth: 2,
			stroke: "#61B7CF",
			joinstyle: "round",
			outlineStroke: "white",
			outlineWidth: 2
		},
		// .. and this is the hover style.
		connectorHoverStyle = {
			strokeWidth: 3,
			stroke: "#216477",
			outlineWidth: 5,
			outlineStroke: "white"
		},
		endpointHoverStyle = {
			fill: "#216477",
			stroke: "#216477"
		},
		// the definition of source endpoints (the small blue ones)
		sourceEndpoint = {
			endpoint: "Dot",
			paintStyle: {
				stroke: "#7AB02C",
				fill: "transparent",
				radius: 7,
				strokeWidth: 1
			},
			isSource: true,
			connector: ["Flowchart", {
				stub: [40, 60],
				gap: 10,
				cornerRadius: 5,
				alwaysRespectStubs: true
			}],
			connectorStyle: connectorPaintStyle,
			hoverPaintStyle: endpointHoverStyle,
			connectorHoverStyle: connectorHoverStyle,
			dragOptions: {},
			overlays: [
				["Label", {
					location: [0.5, 1.5],
					label: "Drag",
					cssClass: "endpointSourceLabel",
					visible: false
				}]
			]
		},
		// the definition of target endpoints (will appear when the user drags a connection)
		targetEndpoint = {
			endpoint: "Dot",
			paintStyle: {
				fill: "#7AB02C",
				radius: 7
			},
			hoverPaintStyle: endpointHoverStyle,
			maxConnections: -1,
			uniqueEndpoint: true,
			dropOptions: {
				hoverClass: "hover",
				activeClass: "active"
			},
			isTarget: true,
			overlays: [
				["Label", {
					location: [0.5, -0.5],
					label: "Drop",
					cssClass: "endpointTargetLabel",
					visible: false
				}]
			]
		},
		// 连接时事件
		init = function(connection, type) {
			if(type == 'connection') {
				if('call' == connection.getParameter('type')) {
					connection.getOverlay("label").setLabel('调用');
				}
				//condef[connection.getParameter("sid")] = connection.getParameter("sid") + " " + connection.getParameter('type') + " " + connection.getParameter("tid");
			} else {
				//condef[connection.getParameter("sid")] = null;
				//$(condef).removeAttr(connection.getParameter("sid"));
			}
		};
	var addComponetToCanve = function(funcDef) {
			window.jsp.batch(function() {
				var data = funcDef.nodes;
				for(var p = 0; p < data.length; p++) {
					var point = data[p],
						sourceAnchors = point.output,
						targetAnchors = point.input;
					$("#canvas").append('<div class="window jtk-node node-' + point.type + '" id="flowchart' + point.id + '" style="left:' + point.pos.left + ';top:' + point.pos.top + ';"><strong>' + point.text + '</strong><br/><br/></div>');

					for(var i = 0; i < sourceAnchors.length; i++) {
						var sourceUUID = "sourceEndpoint_" + point.id + '_' + i;
						window.jsp.addEndpoint("flowchart" + point.id, $.extend({}, sourceEndpoint, {
							parameters: {
								"sid": point.id,
								"stext": point.text,
								"type": point.type
							}
						}), {
							anchor: sourceAnchors[i],
							uuid: sourceUUID
						}, );
					}
					for(var j = 0; j < targetAnchors.length; j++) {
						var targetUUID = "targetEndpoint_" + point.id + '_' + j;
						window.jsp.addEndpoint("flowchart" + point.id, $.extend({}, targetEndpoint, {
							parameters: {
								"tid": point.id,
								"ttext": point.text
							}
						}), {
							anchor: targetAnchors[j],
							uuid: targetUUID
						});
					};
				}

				var cons = funcDef.conections;
				$(cons).each(function() {
					window.jsp.connect({
						uuids: ["sourceEndpoint_" + this.source, "targetEndpoint_" + this.target]
					});
				});
				// 绑定单元拖动事件 
				bindEvent();
			});
		},
		addComponetToTool = function(type, data) {
			if(data) {
				for(var i = 0; i < data.length; i++) {
					var item = data[i];
					$("#" + type + "_node").append('<div class="window jtk-node node-' + item.type + '" data-id="' + item.id + '" data-type="' + item.type + '" data-output="' + item.output.join("|") + '" data-input="' + item.input.join("|") + '"><strong>' + item.text + '</strong></div>');
				}
				bindCompnetEvent(type);
			}
		};
	var loadFuncDef = function(funcId) {
			$.LogicEditor.loadFuncDef(fileID, funcId, function(data) {
				// 清空面板上的所有元素
				$(".flowchart-area .window").each(function() {
					window.jsp.remove($(this).attr("id"));
				});
				// 重定位到中心
				$(".flow-panzoom").css("transform", "matrix(1, 0, 0, 1, 0, 0)");
				// 加载流程
				addComponetToCanve(data);
			});
		},
		loadBaseComponet = function() {
			// 加载基础和高级的元素
			$.Common.Http.Get("../../data/test_basic_node.json", function(data) {
				if(data) {
					addComponetToTool("basic", data.basic);
					addComponetToTool("advanced", data.advanced);
				}
			});
		},

		loadUserComponet = function() {
			// 加载用户自定义的元素
			$.Common.Http.Get("../../data/test_func.json", function(data) {
				if(data) {
					addComponetToTool("user", data);
				}
			});
		};

	var minScale = 0.4;
	var maxScale = 2;
	var incScale = 0.1;
	var plumb = null;
	var $container = $(".flow-container");
	var bindEvent = function() {
		// 使能拖拽
		$container.find(".flowchart-area .window").draggable({
			start: function(e) {
				var pz = $container.find(".flow-panzoom");
				currentScale = pz.panzoom("getMatrix")[0];
				$(this).css("cursor", "move");
				pz.panzoom("disable");
			},
			drag: function(e, ui) {
				ui.position.left = ui.position.left / currentScale;
				ui.position.top = ui.position.top / currentScale;
				//if($(this).hasClass("jsplumb-connected")) {
				window.jsp.repaintEverything();
				//}
			},
			stop: function(e, ui) {
				var nodeId = $(this).attr('id');
				window.jsp.repaintEverything();
				$(this).css("cursor", "");
				$container.find(".flow-panzoom").panzoom("enable");
			}
		});
	};

	// 绑定组件的事件
	var bindCompnetEvent = function(type) {
		// 使能拖拽
		var selector = type ? "#" + type + ".func-tool" : ".func-tool";
		$(selector).find(".window").draggable({
			helper: "clone",
			containment: [$(".left-tool").is(":hidden") ? 0 : $(".left-tool").width(), 0, document.body.clientWidth - 100, document.body.clientHeight - 105],
			start: function(e) {

			},
			drag: function(e, ui) {

			},
			stop: function(e, ui) {
				console.log(e);
				var $target = $(e.target);
				// 如果在组件区域，则不添加
				var $obj = $(".left-tool");
				if(ui.offset.left > (document.body.clientWidth - $obj.width() - $(e.target).width()) &&
					ui.offset.left < (document.body.clientWidth) &&
					ui.offset.top > 0 &&
					ui.offset.top < $obj.height()) {
					return;
				}
				var id = $target.attr("data-id") + (new Date().getTime());
				var data = [];
				var matrix = $container.find(".flow-panzoom").panzoom("getMatrix");
				var offsetLeft = $(".left-tool").is(":hidden") ? 0 : $(".left-tool").width();
				var outputAry = ($target.attr("data-output") || "").split("|") || [];
				outputAry = outputAry.notempty();
				$(outputAry).each(function(ix) {
					if(this.indexOf(",") >= 0) {
						var strAry = this.split(",");
						var intAry = [];
						strAry.forEach(function(data, index, arr) {
							intAry.push(+data);
						});
						outputAry[ix] = intAry;
					}
				});
				var inputAry = ($target.attr("data-input") || "").split("|") || [];
				inputAry = inputAry.notempty();
				$(inputAry).each(function(ix) {
					if(this.indexOf(",") >= 0) {
						var strAry = this.split(",");
						var intAry = [];
						strAry.forEach(function(data, index, arr) {
							intAry.push(+data);
						});
						inputAry[ix] = intAry;
					}
				});
				data.push({
					id: id,
					text: $target.text(),
					type: $target.attr("data-type"),
					output: outputAry,
					input: inputAry,
					pos: {
						top: (ui.offset.top - matrix[5] + 4) + "px",
						left: (ui.offset.left - matrix[4] - offsetLeft) + "px"
					}
				});
				addComponetToCanve({
					nodes: data
				});
			}
		});
	};

	// 加载元素列表
	$.LogicEditor.loadFuncs(fileID, function(data) {
		$(".func-list").empty();
		$(data).each(function() {
			$(".func-list").append('<div class="func-item" id="' + this.id + '"><h3>' + this.text + '</h3>' +
				'<p>' + this.desc + '</p></div>');
		});
		$(".func-list .func-item").click(function() {
			loadFuncDef($(this).attr("id"));
		});
	});

	// 初始化画板
	jsPlumb.ready(function() {
		var instance = window.jsp = jsPlumb.getInstance({
			// default drag options
			DragOptions: {
				cursor: 'pointer',
				zIndex: 2000
			},

			ConnectionOverlays: [
				["Arrow", {
					location: 1,
					visible: true,
					width: 11,
					length: 11,
					id: "ARROW",
					events: {
						click: function() {
							alert("you clicked on the arrow overlay")
						}
					}
				}],
				["Label", {
					location: 0.1,
					id: "label",
					cssClass: "aLabel",
					events: {
						tap: function() {
							alert("hey");
						}
					}
				}]
			],
			Container: "canvas"
		});
		var basicType = {
			connector: "StateMachine",
			paintStyle: {
				stroke: "red",
				strokeWidth: 4
			},
			hoverPaintStyle: {
				stroke: "blue"
			},
			overlays: [
				"Arrow"
			]
		};
		instance.registerConnectionType("basic", basicType);
		// 绑定单元拖动事件
		bindEvent();
		$panzoom = $container.find('.flow-panzoom').panzoom({
				minScale: minScale, //0.4
				maxScale: maxScale, //2
				increment: incScale, //0.1
				cursor: "",
				ignoreChildrensEvents: true,
			}).on("panzoomstart", function(e, pz, ev) {
				$panzoom.css("cursor", "move"); //set "move" cursor on start only
			})
			.on("panzoomend", function(e, pz) {
				$panzoom.css("cursor", ""); //restore cursor
			});
		$panzoom.parent()
			.on('mousewheel.focal', function(e) {
				// 滚轮操作
			})
			//on start store initial offsets and mouse coord
			.on("mousedown touchstart", function(ev) {
				var matrix = $container.find(".flow-panzoom").panzoom("getMatrix");
				var offsetX = matrix[4];
				var offsetY = matrix[5];
				var dragstart = {
					x: ev.pageX,
					y: ev.pageY,
					dx: offsetX,
					dy: offsetY
				};
				$(ev.target).css("cursor", "move");
				$(this).data('dragstart', dragstart);
			})
			//calculate mouse offset from starting pos and apply it to panzoom matrix
			.on("mousemove touchmove", function(ev) {
				var dragstart = $(this).data('dragstart');
				if(dragstart) {
					var deltaX = dragstart.x - ev.pageX;
					var deltaY = dragstart.y - ev.pageY;
					var matrix = $container.find(".flow-panzoom").panzoom("getMatrix");
					matrix[4] = parseInt(dragstart.dx) - deltaX;
					matrix[5] = parseInt(dragstart.dy) - deltaY;
					$container.find(".flow-panzoom").panzoom("setMatrix", matrix);
				}
			})
			.on("mouseup touchend touchcancel", function(ev) {
				$(this).data('dragstart', null);
				$(ev.target).css("cursor", "");
			});

		// ================================================================
		// 初始化
		// ================================================================
		instance.batch(function() {
			// listen for new connections; initialise them the same way we initialise the connections at startup.
			instance.bind("connection", function(connInfo, originalEvent) {
				init(connInfo.connection, 'connection');
			});

			instance.bind("connectionDetached", function(connInfo, originalEvent) {
				init(connInfo.connection, 'detached');
			});

			// THIS DEMO ONLY USES getSelector FOR CONVENIENCE. Use your library's appropriate selector
			// method, or document.querySelectorAll:
			//jsPlumb.draggable(document.querySelectorAll(".window"), { grid: [20, 20] });

			// connect a few up
			/*instance.connect({
				uuids: ["Window2BottomCenter", "Window3TopCenter"],
				editable: true
			});
			instance.connect({
				uuids: ["Window2LeftMiddle", "Window4LeftMiddle"],
				editable: true
			});
			instance.connect({
				uuids: ["Window4TopCenter", "Window4RightMiddle"],
				editable: true
			});
			instance.connect({
				uuids: ["Window3RightMiddle", "Window2RightMiddle"],
				editable: true
			});
			instance.connect({
				uuids: ["Window4BottomCenter", "Window1TopCenter"],
				editable: true
			});
			instance.connect({
				uuids: ["Window3BottomCenter", "Window1BottomCenter"],
				editable: true
			});*/
			//

			//
			// listen for clicks on connections, and offer to delete connections on click.
			//
			instance.bind("click", function(conn, originalEvent) {
				// if (confirm("Delete connection from " + conn.sourceId + " to " + conn.targetId + "?"))
				//   instance.detach(conn);
				// conn.toggleType("basic");
				console.log("click");
			});

			instance.bind("connectionDrag", function(connection) {
				console.log("connection " + connection.id + " is being dragged. suspendedElement is ", connection.suspendedElement, " of type ", connection.suspendedElementType);
			});

			instance.bind("connectionDragStop", function(connection) {
				console.log("connection " + connection.id + " was dragged");
			});

			instance.bind("connectionMoved", function(params) {
				console.log("connection " + params.connection.id + " was moved");
			});
		});

		jsPlumb.fire("jsPlumbDemoLoaded", instance);

		//回显数据
		loadFuncDef();
		loadBaseComponet();
		loadUserComponet();
	});
});